1、your react app suddenly becomes slow after adding new features, how do you find and fix the issue?

可以这样类比来想:think of like you phone is slowing down after you install too many apps, you need to find out which app is using the resourses and is making you phone slow.

1、we can use chrome devtools, and in the performance tab, and see what is taking the most time.

2、we can use react devtools chrome extension, we can track unneccessary rerenders or infinite loop of rerenders.

3、we can use React.memo and useCallback to making app fast and tracking where is slow.

4、I will check if there are any large amount of data to render at once. usually we render only the visible amount of data, use packages like react.window or react.virtulized.

5、avoid inline functions and objects。

Inline functions and objects are recreated on every render, which can cause child components to re-render unnecessarily — especially if those children depend on referential equality (React.memo, dependency arrays, etc.).

Example problem:

Every render:

So Child thinks props changed → re-renders every time, even if nothing actually changed.

How to fix it:

①Use useCallback for functions

②Use useMemo for objects/arrays

 

上面的步骤要理解,然后简要的答案先说出来:

“I first profile the app using React DevTools to identify which components became slow. Then I check for unnecessary re-renders, expensive operations in render, problematic effects, or network calls happening too frequently.

“I also check if I accidentally introduced inline functions or inline objects. Those get recreated on every render, which can break memoization and cause unnecessary re-renders. If I see that pattern, I move them into useCallback or useMemo to keep stable references.”

Once I find the root cause, I optimize it—using memoization, moving state, cleaning up effects, or applying code splitting. My approach is always: measure → identify → fix → re-measure.”

2、how do you prevent a login page from being accessible after the user is logged in?

The general idea is:If the user is already authenticated, redirect them away from the login page.

  1. Using React Router (most common)

You check the auth state, and if the user is logged in, redirect them:

Explanation:

This ensures the login page is never visible to authenticated users.

  1. With a Protected Route Wrapper

Sometimes I create a wrapper:

Then wrap the route:

  1. Server-side check (if SSR or backend routing)

If the backend renders the page, the server can also redirect if the session exists.

理解上面的内容后,简要回答:

“I prevent the login page from being accessible after login by checking whether the user is authenticated. If the user is already logged in, I immediately redirect them to a protected page like the dashboard. In React Router, this usually means returning a <Navigate> component when user exists. This ensures the login page is only visible to unauthenticated users.”

3、how do you handle API errors gracefully in the UI?

  1. Show a clear, user-friendly message

Users should never see raw server errors like “500 Internal Server Error”.

Example:

This keeps the UI clean and understandable.

  1. Use try/catch around API calls

In React components or services:

Then the UI reacts to that error state.

  1. Display fallback UI

For example:

  1. Handle different error types

I often show different messages depending on the error:

This makes the UI feel professional and predictable.

  1. If using React Query

React Query makes this much easier:

React Query automatically gives:

So the UI can handle errors more gracefully.

理解上面之后,简要的回答:

“I handle API errors by wrapping network calls in try/catch or using libraries like React Query / Axios, capturing both HTTP-error responses and network exceptions. I store the error state (e.g. using useState or React Query’s error / isError flags), and show a user-friendly fallback UI — such as an error message, a toast/notification, or a retry button wrapped in a conditional render. For critical component errors I can also use a global error boundary (via ErrorBoundary) to catch rendering or lifecycle exceptions so the whole UI doesn’t break. For HTTP status codes I differentiate behaviors — e.g. 401 leads to redirect to login, 403 shows “access denied”, 400 shows validation feedback. I may also implement retry logic or exponential-backoff on failures (especially for transient network errors) and log errors (to console or a logging service) for debugging.”

4、a component is fetching the same data multiple times unneccessarily. How do you fix it?

  1. Fix the useEffect dependency array

One of the most common causes is a missing or incorrect dependency array:

❌ Bad (fetch runs every render)

✅ Good (runs only once on mount)

Or if dependencies are required, ensure they don’t change on every render.

  1. Memoize functions with useCallback

If the fetch function is declared inline and passed to children or used inside effects, it may be recreated every render, causing repeated calls.

❌ Bad

✅ Good

  1. Memoize computed values with useMemo

If parameters for your fetch are created inline (like an object), the reference changes every time:

✔️

  1. Lift state up (avoid fetching in many components)

Sometimes multiple sibling components fetch the same data.

Solution:

This way the data is fetched once and shared.

  1. Use a data-fetching library (React Query / RTK Query)

Tools like React Query or Redux Toolkit Query automatically:

React Query example:

Duplicate calls are automatically prevented.

  1. Ensure no conditional renders cause re-mounting

Some developers accidentally remount a component repeatedly:

If isOpen toggles repeatedly, the component unmounts and remounts, triggering useEffect again.

Fix:

理解上面的内容后,简要的回答:

“First, I check the useEffect dependency array — missing or unstable dependencies often cause repeated fetch calls. Then I make sure the fetch function is memoized with useCallback and any params with useMemo, so they don’t change every render. If several components need the same data, I move the fetching logic into a global store, such as React Context or Redux, so the data is fetched once and reused everywhere. For even more control, I use libraries like React Query or Redux Toolkit Query, which provide request deduplication, caching, and stale-while-revalidate behavior out of the box. In short: stabilize dependencies, avoid remounting, and centralize or cache the data so it only gets fetched once.”

5、how do you optimize bundle size in a large react app?

可以这样想:think of this like you are travelling, you don't take your complete cupboard or wardrobe with you, you take neccessary some part of it in the travel.

Just like that, whenever you writing thousands of files in your app, you don't need to ship everything to the production.So you need to bundle it and organize it somehow so that it will take minimum size on the user's device and it will be efficient for the performance.

  1. Code splitting → use React.lazy or Suspense
  2. Tree Shaking → use vite or webpack to remove unused imports
  3. Dynamic imports → use dynamic imports, import() to avoid some code to be bundled in the main chunk
  4. Compress assets → images or fonts

理解了上面的内容之后,简要回答:

“I usually optimize bundle size by focusing on code splitting, dependency management, and build-time optimizations. First, I implement route-level code splitting using React.lazy and Suspense, so the app only loads what’s needed for the current page. For heavier features, I use dynamic imports or component-level lazy loading to avoid shipping large chunks upfront. I also regularly analyze the bundle using tools like Webpack Bundle Analyzer or Vite’s analyze plugin to identify large or unused dependencies. If a library is too heavy, I try to replace it with a smaller alternative, remove unused code, or tree-shake it. On the build side, I make sure features like tree-shaking, minification, and dead-code elimination are enabled, and I avoid importing entire libraries when I only need specific modules. For assets, I optimize images, use *.svg components instead of PNGs, and rely on CDNs where possible. Overall, the approach is: split the code, trim unnecessary dependencies, enable build optimizations, and continuously analyze the bundle to keep it lean.”

6、how do you handle a form with 20+ fields efficiently?

当面试官问large forms,他们想要看到你是否能够优化form、维持状态的能力。

这是Shubham Kulkarni | Coding and Interviews这位老师的回答要点。

1、use form management library like formik or react hook form,

2、structure the form to logical steps or sections.

3、use controlled components,

4、use zod library to validate.

 

下面是chatgpt的回答:

✅ 1. Group related fields into logical sections

Don’t treat 20 fields as 20 individual states. Instead, think of your form as sections:

This gives you:

✔ Better UI/UX ✔ Smaller components ✔ Cleaner validation

Example structure:

✅ 2. Use a form library — don’t manage 20 states manually

Best option: React Hook Form (RHF)

It handles:

For 20+ fields, RHF is dramatically better than useState or even Formik.

Example:

✅ 3. Store all form values in one place (not 20 states)

For large forms, do NOT use:

Instead:

Or if using useState manually:

✅ 4. Extract repeating field logic into reusable components

If many fields share:

Create a component:

Now your form becomes:

✅ 5. Use a schema validator (Zod/Yup) to avoid manual checks

With 20+ fields, writing if (!name) error... everywhere becomes painful.

Use Zod:

Integrate with RHF:

Now all validation is centralized and reusable.

✅ 6. Use dynamic generation (optional but powerful)

If fields share patterns, define them as config:

Render automatically:

Great for 20–100 fields.

✅ 7. Split the form into tabs or steps if possible

For UX improvement:

Use a stepper or wizard.

Better:

✔ Less intimidating ✔ Faster rendering ✔ Validation per step

✅ 8. Memoize heavy components

For example, expensive dropdowns.

RHF already minimizes re-renders, but memoization helps further.

🧪 9. For huge forms → Use RHF + Suspense + lazy-loaded sections

If your sections are large:

Better performance for enterprise apps.

🎯 Final recommended stack for 20+ fields

LayerRecommendation
Form libraryReact Hook Form
ValidationZod
StructureMultiple components (sections)
ExtraConfig-driven generation for repeated patterns

“For a form with 20 or more fields, I try to handle it efficiently by combining structure, reusable components, and proper form libraries. First, I group related fields into sections or components to keep the UI organized and maintainable.

Then, I use a form library like React Hook Form, which manages all field states centrally and minimizes re-renders, instead of using separate useState for each field. For validation, I rely on schema-based validators like Zod or Yup so that all rules are centralized and type-safe. I also extract repeated field patterns into reusable input components, and optionally generate fields dynamically from a config object. For very large forms, I consider splitting the form into steps or tabs to improve UX and performance.

Overall, my approach is: centralized state, reusable components, schema validation, and structured sections to handle large forms efficiently.”

7、your react app needs to support dark mode.How do you implement it?

面试管想听到的要点就是:the theme state should be global, so whenever you toggle the theme at the global state, it will be auto reflected in the children level.

1、I will check whether the dark mode is user preference based or system based.

2、if it's system based.I will use prefers-color-scheme media query to detect system preference on first load.then set the theme mode.

3、if it's user mode, I often rely on react context or redux to set global state, and rely on CSS variables or tailwindcss to set dark mode.

简要回答:

“To implement dark mode in a React app, I usually manage a theme state at the top level, using either React Context, Redux, or a global store like Zustand. I store the user’s preference in localStorage so it persists across sessions, and I use a toggle button in the UI to switch between light and dark themes. For styling, I often rely on CSS variables or a utility framework like Tailwind CSS, which supports dark mode with the dark: variant. Components then automatically adapt by referencing the theme variables, and I can also add a class like dark on the root element to switch the entire app. In short, the approach is: store theme in global state, persist the preference, and style components using CSS variables or a framework that supports dark mode

8、how do you prevent XSS(Cross-Site Scripting) in frontend apps?

关键词拆解:

  1. XSS (Cross-Site Scripting)

    • 一种常见的前端安全漏洞,攻击者可以注入恶意脚本到网页,执行在其他用户浏览器中。
    • 可能导致 cookie泄露、用户数据被篡改、劫持会话 等。
  2. Frontend apps

    • 前端应用(React / Vue / Angular 等),主要是 浏览器端防护

核心考点:

拆解小问题:

  1. 为什么会发生 XSS?

    • 用户输入未经处理直接插入到 DOM → 执行脚本
  2. 前端可以做什么?

    • 不要插入未处理的 HTML
    • 框架的自动转义机制
    • 对必须插入的 HTML 做 清理/过滤
  3. 可用工具 / 方法?

    • React 自动转义 {userInput}
    • dangerouslySetInnerHTML + DOMPurify
    • 禁用 eval()
    • 内容安全策略 (CSP)

“To prevent XSS attacks in frontend apps, I follow a combination of output encoding, input sanitization, and safe rendering practices. First, I never inject raw HTML into the DOM. For example, in React, I avoid using dangerouslySetInnerHTML unless absolutely necessary, and if I do, I sanitize the content first using libraries like DOMPurify. Second, I validate and sanitize any user input on both the client and the server, especially if it will be displayed later. Third, I rely on the framework’s built-in protections—React automatically escapes content rendered inside JSX, so normal expressions like {userInput} are safe by default. Finally, I also follow general best practices: avoid using eval(), ensure third-party scripts are trusted, and apply a strong Content Security Policy (CSP) at the server level to prevent inline script execution. Overall, the approach is: sanitize inputs, escape outputs, avoid raw HTML, and leverage framework protections to prevent XSS.”

9、how do you handle offline/online state gracefully in react with service workers?

1️⃣ 题目关键词

  1. Offline/Online state

    • 意思是用户的网络状态:在线(online)还是离线(offline)。
    • 你的应用需要知道用户是在线还是离线,并作出对应处理。
  2. Gracefully

    • 不只是知道状态,还要让用户体验顺畅。
    • 例如:显示提示、缓存数据、避免应用崩溃。
  3. React

    • 说明你需要在 React 组件里管理这个状态。
    • 可能涉及 stateContextRedux
  4. Service Workers

    • 浏览器的一种后台脚本,用来缓存资源和数据,实现 离线功能
    • 它允许你的应用在没有网络时仍然能运行一部分功能。

2️⃣ 拆解后的思路

你可以把题目拆解成三个小问题:

(A) 如何在 React 中检测在线/离线状态?

(B) 如何用 Service Worker 支持离线功能?

(C) 如何在重新上线时同步数据?

3️⃣ 组合成回答框架

  1. 检测状态navigator.onLine + online/offline 事件
  2. 更新 UI → 显示横幅、禁用某些功能、提示用户
  3. 离线功能 → Service Worker 缓存静态资源和 API 数据
  4. 重新上线同步 → background sync 或手动发送缓存的请求

老师的要点:

1、I will use navigator.onLine API provided by the browser, to detect network status. And listen to the online and offline events.

2、use service workers to cache critical assets and API responses.

 

“To handle offline and online states in a React app, I usually combine browser APIs with Service Workers.

 

First, I detect network status using the navigator.onLine property and listen to the online and offline events, updating a global state or React Context so components can react accordingly. For example, I can show a banner or toast to inform users they are offline.

 

Second, I use a Service Worker—for example, via Workbox or a PWA setup—to cache critical assets and API responses. This allows the app to function in offline mode and serve cached content.

 

For data syncing, when the user goes back online, I can implement background sync to send queued updates to the server.

In short, my approach is: listen to network events, update UI reactively, cache resources with a Service Worker, and optionally queue requests for later syncing to provide a seamless offline/online experience.”

10、Production is not getting the latest deployed update unless in incognito.How do you solve this?

关键词拆解:

  1. Production is not getting the latest update

    • 用户在生产环境访问网站时,看到的仍是旧版本。
    • 说明前端部署了新版本,但浏览器加载的是缓存的旧文件。
  2. Unless in incognito

    • 在隐身模式下正常显示最新版本。
    • 隐身模式通常不会使用浏览器缓存或 Service Worker 缓存 → 问题在 缓存策略

核心考点:

拆解小问题:

  1. 为什么普通用户看到旧版本?

    • 浏览器缓存旧 JS/CSS 文件,比如说打包后的main.js,这个文件名没有变化的话,浏览器不会默认获取新的。
    • CDN 缓存旧文件
    • Service Worker 缓存旧资源
  2. 为什么隐身模式正常?

    • 隐身模式不会使用旧缓存 → 能直接获取最新资源
  3. 如何解决?

    • 强制浏览器/用户获取最新文件,Use content hashing for JS/CSS filenames in the build process
    • 设置正确的 HTTP 缓存策略
    • 或在 Service Worker 中处理缓存更新

简要回答:

“This is usually a caching issue. When users see the old version in production but incognito works, it means the browser or a service worker is serving cached files. To fix this, I would:

  1. Use content hashing for JS/CSS filenames in the build process, so each new deployment has unique filenames and browsers fetch the new files automatically.
  2. Ensure HTTP cache headers are correctly set, like Cache-Control: no-cache or short max-age for index.html, so the HTML always checks for new bundles.
  3. If using a Service Worker, implement cache versioning and update logic, so the new assets replace the old cached ones. In short, the solution is to manage caching properly through content hashing, cache headers, and service worker update strategy, so users always get the latest version without relying on incognito mode.”